/**
 * @auth Ning
 * @purpose COMPLEX NUMBER! AS THE CLASS NAME, THE COMPLEX NUMBER DEFINED BY REAL PART AND IMAGINARY PART...
 * @date 2009-8-25
 * */	
package extendedmath
{
		
	public class ComplexNumber
	{
		//START...
		
		//PROPERTY...
		private var _real:Number;
		
		private var _imaginary:Number;
		
		
		//CONSTRUCTOR...
		public function ComplexNumber(real:Number = 0,imaginary:Number = 0)
		{
			
			if(isNaN(imaginary) || isNaN(real))
			{
				
				throw new MathError(MathError.COMPLEX_NUMBER_ERROR_01["message"],MathError.COMPLEX_NUMBER_ERROR_01["id"]);
				
				return;
				
			}
			
			this.real = real;
			
			this.imaginary = imaginary;
		
		}
		
		//METHODS...
		
		//set the real part of this complex number...
		public function set real(num:Number):void
		{
			
			_real = num;
			
		}
				
		//get the  real part of this complex number...
		public function get real():Number
		{
			
			return _real;
			
		}
		
		//set the imaginary part of this complex number...
		public function set imaginary(num:Number):void
		{

			_imaginary = num;			
			
		}
		
		//get the imaginary part of this complex number...
		public function get imaginary():Number
		{
			
			return _imaginary; 
			
		}
		
		//get the mode of this complex number...
		public function get mode():Number
		{
			
			return Math.sqrt(_real * _real + _imaginary * _imaginary);
									
		}
		
		//get complex argument... z＝r *（cosθ＋sinθi） r: mode, θ: complex argument...
		public function get complexArg():Number
		{
			
			return (Math.atan2(imaginary , real));
			
		}
		
		////get standard argument...
		public function getStdArgumet():Number
		{
			
			return complexArg;
			
		}
		
		
		//set triangle form...
		public function setTriangleForm(r:Number,angle:Number):void
		{
												
			_real =  r * Math.cos(angle);
			
			_real = Math.floor(_real * 1000) / 1000;			
						
			_imaginary =  r *  Math.sin(angle);
			
			_imaginary = Math.floor( _imaginary * 1000 ) / 1000;
			
		}
		
		
		//get complex number index part... z＝r * exp(θi)
		public function get index():Number
		{
			
			return Math.exp(complexArg);
			
		}
		
		
		//compare with othe complex number...
		public function equls(complexNum:ComplexNumber):Boolean
		{
			
			return (real == complexNum.real && imaginary == complexNum.imaginary);
			
		}
		
		//check specfic complex number is the conjugate complex number of this or not....
		public function isConjugate(complexNum:ComplexNumber):Boolean
		{
			
			return (real == complexNum.real && imaginary == -complexNum.imaginary);  
			
		}
		
		//is this a pure complex number?
		public function isPure():Boolean
		{
			
			return (real == 0);
			
		}
		
		//opration...
		
		//addition...
		public function add(complexNum:ComplexNumber):ComplexNumber
		{
			
			return new ComplexNumber(real + complexNum.real,imaginary + complexNum.imaginary);
			
		}
		
		//substation...
		public function sub(complexNum:ComplexNumber):ComplexNumber
		{
			
			return new ComplexNumber(real - complexNum.real,imaginary - complexNum.imaginary);
			
		}
		
		//multiplication...
		public function multiply(complexNum:ComplexNumber):ComplexNumber
		{
			
			return new ComplexNumber(real * complexNum.real - imaginary * complexNum.imaginary,imaginary * complexNum.real + real * complexNum.imaginary);
			
		}
		
		//division...
		public function divid(complexNum:ComplexNumber):ComplexNumber
		{
			
			if(complexNum.real == 0 && complexNum.imaginary == 0)
			{
				
				throw new MathError(MathError.COMPLEX_NUMBER_ERROR_02["message"],MathError.COMPLEX_NUMBER_ERROR_02["id"]);
				
				return null;
				
			}
			
			var rez:Number = (real * complexNum.real + imaginary * complexNum.imaginary) / (Math.sqrt(complexNum.real) + Math.sqrt(complexNum.imaginary));
						
			var imz:Number = (imaginary * complexNum.real - real * complexNum.imaginary) / (Math.sqrt(complexNum.real) + Math.sqrt(complexNum.imaginary));
			
			return new ComplexNumber( rez,imz );
			
		}
		
		//exponent arithmetic...
		public function pow(index:Number):ComplexNumber
		{
			
			var result:ComplexNumber = new ComplexNumber;
						
			result.setTriangleForm(Math.pow(mode,index),complexArg * index);
			
			return result;
			
		}
		
		//clone this complex number...
		public function clone():ComplexNumber
		{
			
			return new ComplexNumber(real,imaginary);
		}
		
		//to string format...
		public function toString():String
		{
			
			return "( REZ = " + real + " , IMZ = " + imaginary + " | " + "r = " + mode + " , φ = " + (complexArg / Math.PI * 180) + " )"; 
			
		}
		
		//to normal number format...
		public function toNumber():Number
		{
			
			var num:Number;
			
			if(imaginary == 0)
			{
				
				num = real;
				
			}
			
			return num;
			
		}

		//END...
	}
}